package org.ccay.audit.service.impl;

import java.io.Serializable;

import javax.inject.Named;

import org.ccay.audit.exception.AbstractAuditor;
import org.ccay.audit.vo.LogVO;
import org.ccay.core.expression.MessageEvaluator;
import org.ccay.core.log.Audit;
import org.ccay.core.log.AuditContext;
import org.ccay.core.util.StringUtil;

/**
 * 审计员接口的默认实现。
 * @version:
 */
@Named
public class DefaultAuditor extends AbstractAuditor {
	
	/** 消息表达式估值器 **/
	private MessageEvaluator messageEvaluator = new MessageEvaluator();
	
	/** 
	 * 	构造审计消息
	 * @author chaowangbang
	 * @since Feb 29, 2012
	 * @param context
	 * @return
	 */
	public Serializable buildMessage(AuditContext context) {
		if(context == null) {
			return null;
		}
		
		LogVO log = buildCommonLogVO(context);
		
		Audit audit = context.getMethod().getAnnotation(Audit.class);
		
		/** 
		 * 计算message
		 * 1. 用户指定了message属性，则以message属性优先；
		 * 2. 否则，根据操作的信息生成默认的操作日志消息
		 * 3. 增加计算operation跟module   add by zhaowei  2012-10-26
		 */
		String messageTemplate = audit.message();
		String operationTemplate=audit.operation();//保存operation信息
		String moduleTemplate=audit.module();//保存module信息
		if(!StringUtil.isNullOrEmpty(messageTemplate)){
			String message = convertMessage(context, messageTemplate);//转换message中的EL表达式
			log.setMessage(message);
		}
		if(!StringUtil.isNullOrEmpty(operationTemplate)){
			String operation=convertMessage(context, operationTemplate);//转换operation中的EL表达式
			log.setOperation(operation);
		}
		if(!StringUtil.isNullOrEmpty(moduleTemplate)){
			String module=convertMessage(context, moduleTemplate);//转换module中的EL表达式
			log.setModule(module);
		}	
		log.setLogType(0);
		
		//设置角色ID
		log.setDimension(context.getDimension());
		return log;
	}
	
	/**
	 * 转换EL表达式
	 * @author chaowangbang
	 * @since 2012-10-26
	 * @param context
	 * @param messageTemplate
	 * @return
	 */
	public String convertMessage(AuditContext context, String messageTemplate) {
		String message = null;
		if (!StringUtil.isNullOrEmpty(messageTemplate)) {		
			//通过SpEL计算审计消息
			message = messageEvaluator.evaluate(context, messageTemplate);
		} else {
			// 生成默认格式的审计消息
			message = buildDefaultMessage(context);
		}
		return message;
	}
	
	/** 
	 * 根据操作的信息生成默认的审计消息。
	 * 	
	 * @author chaowangbang
	 * @since Feb 29, 2012
	 * @param context
	 * @return
	 */
	private String buildDefaultMessage(AuditContext context) {
		StringBuilder buf = new StringBuilder();
		buf.append(context.getMethod()+" is called");
		Object[] paramValues = context.getParameterValues();
		if(paramValues.length > 0) {
			buf.append(" with params ").append(buildParamString(paramValues));
		}
		
		return buf.toString();
	}
	
	/** 
	 * 构造参数描述字符串。
	 * 	
	 * @author chaowangbang
	 * @since Feb 29, 2012
	 * @param params
	 * @return
	 */
	private String buildParamString(Object[] params) {
		StringBuilder builder = new StringBuilder();
		for (int i = 0; i < params.length; i++) {
			builder.append(params[i] != null ? params[i].toString() : "null");
			if (i < params.length-1) {
				builder.append(", ");
			}
		}

		return builder.toString();
	}

}
